Introduction

  • Briefly (~1 paragraph) describe the goal of the study, the experimental design, the unit of observation, and any relevant methods.

The goal of the study is to investigate the effects of high-scale urbanization on the body size of Barn Swallows Hirundo rustica gutturalis in China. This study is particularly interesting as it addresses these effects in regards to Swallows of different environmental and climate origins. The design of the experiment was to collect physiological data (body mass and wing length) of breeding individuals from 128 sites at varying stages of urbanization across China. The unit of observation is a singular swallow.


ANALYSIS 1

Question & hypotheses

Biological question

  • State the biological question(s) that this analysis is addressing.

Does urbanization affect body size differently between different sexes?

Statistical analysis

  • Describe the linear model you will use to address your biological question(s): list the response and explanatory variables in your model, including interactions if applicable.

Independent variables will be (1) Urbanization and (2) Sex. I will fit 2 different models (body mass and wing length as response variables). ANOVA, Regression, Assumption tests (data is probably not normal, so log transformations.) In order to answer my biological question, I need to include an interaction term between urbanization and sex.

Analysis & figure(s)

Analysis

Run the analysis

# Load packages
library(tidyverse)
## ── Attaching packages ─────────────────────────────────────── tidyverse 1.3.2 ──
## ✔ ggplot2 3.4.0      ✔ purrr   1.0.1 
## ✔ tibble  3.1.8      ✔ dplyr   1.0.10
## ✔ tidyr   1.2.1      ✔ stringr 1.4.0 
## ✔ readr   2.1.3      ✔ forcats 0.5.2 
## ── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
## ✖ dplyr::filter() masks stats::filter()
## ✖ dplyr::lag()    masks stats::lag()
library(car)
## Loading required package: carData
## 
## Attaching package: 'car'
## 
## The following object is masked from 'package:dplyr':
## 
##     recode
## 
## The following object is masked from 'package:purrr':
## 
##     some
library(cowplot)
library(emmeans)
library(DHARMa)
## This is DHARMa 0.4.6. For overview type '?DHARMa'. For recent changes, type news(package = 'DHARMa')
# Set contrasts
options(contrasts=c("contr.poly","contr.sum"))

# Import the dataset:
# Code to import a dataset
BodySize_data <- read.csv("/Users/winny/Downloads/doi_10-10/Liu_Winson Dataset/BodySize_data.csv", stringsAsFactors=TRUE)

# Does urbanization affect body size [Body mass / Wing length] differently between different sexes?

# Check for missing values
is.na(BodySize_data$sex)
##   [1] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
##  [13] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
##  [25] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
##  [37] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
##  [49] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
##  [61] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
##  [73] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
##  [85] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
##  [97] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
## [109] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
## [121] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
## [133] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
## [145] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
## [157] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
## [169] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
## [181] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
## [193] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
## [205] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
## [217] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
## [229] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
## [241] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
## [253] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
## [265] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
## [277] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
## [289] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
## [301] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
## [313] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
## [325] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
## [337] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
## [349] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
is.na(BodySize_data$urbanization)
##   [1] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
##  [13] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
##  [25] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
##  [37] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
##  [49] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
##  [61] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
##  [73] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
##  [85] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
##  [97] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
## [109] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
## [121] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
## [133] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
## [145] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
## [157] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
## [169] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
## [181] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
## [193] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
## [205] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
## [217] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
## [229] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
## [241] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
## [253] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
## [265] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
## [277] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
## [289] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
## [301] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
## [313] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
## [325] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
## [337] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
## [349] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
is.na(BodySize_data$body.mass)
##   [1] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
##  [13] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
##  [25] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
##  [37] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
##  [49] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
##  [61] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
##  [73] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
##  [85] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
##  [97] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
## [109] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
## [121] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
## [133] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
## [145] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
## [157] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
## [169] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
## [181] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
## [193] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
## [205] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
## [217] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
## [229] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
## [241] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
## [253] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
## [265] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
## [277] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
## [289] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
## [301] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
## [313] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
## [325] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
## [337] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
## [349] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
is.na(BodySize_data$wing.length)
##   [1] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
##  [13] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
##  [25] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
##  [37] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
##  [49] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
##  [61] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
##  [73] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
##  [85] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
##  [97] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
## [109] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
## [121] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
## [133] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
## [145] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
## [157] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
## [169] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
## [181] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
## [193] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
## [205] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
## [217] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
## [229] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
## [241] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
## [253] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
## [265] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
## [277] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
## [289] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
## [301] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
## [313] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
## [325] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
## [337] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
## [349] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
# Fit the model: (body mass)
# Assumptions failed
mod1 = lm(body.mass ~ urbanization * sex, data=BodySize_data)

# Assumptions passed
modlog1 = lm(log(body.mass) ~ urbanization*sex, data=BodySize_data)

# Analysis
# Anova
Anova(modlog1, type=3)
## Anova Table (Type III tests)
## 
## Response: log(body.mass)
##                  Sum Sq  Df    F value    Pr(>F)    
## (Intercept)      958.72   1 1.3234e+05 < 2.2e-16 ***
## urbanization       0.30   1 4.0729e+01 5.466e-10 ***
## sex                0.12   1 1.6658e+01 5.533e-05 ***
## urbanization:sex   0.01   1 9.4780e-01    0.3309    
## Residuals          2.57 355                         
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
# Summary
summary(modlog1)
## 
## Call:
## lm(formula = log(body.mass) ~ urbanization * sex, data = BodySize_data)
## 
## Residuals:
##       Min        1Q    Median        3Q       Max 
## -0.270960 -0.051910 -0.001694  0.059191  0.262592 
## 
## Coefficients:
##                      Estimate Std. Error t value Pr(>|t|)    
## (Intercept)         2.8063587  0.0077143 363.787  < 2e-16 ***
## urbanization       -0.0007048  0.0001104  -6.382 5.47e-10 ***
## sex.L              -0.0445267  0.0109096  -4.081 5.53e-05 ***
## urbanization:sex.L -0.0001521  0.0001562  -0.974    0.331    
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 0.08511 on 355 degrees of freedom
## Multiple R-squared:  0.2289, Adjusted R-squared:  0.2224 
## F-statistic: 35.14 on 3 and 355 DF,  p-value: < 2.2e-16
# Fit the model 2: (wing length)
# Assumptions failed
mod2 = lm(wing.length ~ urbanization * sex, data=BodySize_data)

# Assumptions failed
modlog2 = lm(log(wing.length) ~ urbanization * sex, data=BodySize_data)

modglm2 = glm(wing.length ~ urbanization*sex, data=BodySize_data, family="Gamma")

# Analysis
# Anova
Anova(modglm2, type=3)
## Analysis of Deviance Table (Type III tests)
## 
## Response: wing.length
##                  LR Chisq Df Pr(>Chisq)    
## urbanization      27.8007  1  1.345e-07 ***
## sex                6.3275  1    0.01189 *  
## urbanization:sex   0.7445  1    0.38822    
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
# Summary
summary(modglm2)
## 
## Call:
## glm(formula = wing.length ~ urbanization * sex, family = "Gamma", 
##     data = BodySize_data)
## 
## Deviance Residuals: 
##       Min         1Q     Median         3Q        Max  
## -0.067952  -0.015894  -0.001332   0.015694   0.095466  
## 
## Coefficients:
##                      Estimate Std. Error t value Pr(>|t|)    
## (Intercept)         8.473e-03  1.950e-05 434.468  < 2e-16 ***
## urbanization        1.481e-06  2.808e-07   5.276  2.3e-07 ***
## sex.L              -6.935e-05  2.758e-05  -2.514   0.0124 *  
## urbanization:sex.L -3.427e-07  3.971e-07  -0.863   0.3888    
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## (Dispersion parameter for Gamma family taken to be 0.0006413438)
## 
##     Null deviance: 0.26669  on 358  degrees of freedom
## Residual deviance: 0.22685  on 355  degrees of freedom
## AIC: 1802.5
## 
## Number of Fisher Scoring iterations: 3

Check assumptions

# 1: Body Mass
# Check assumptions (mod1)
plot(mod1, which=2) # Fails normality assumptions

shapiro.test(mod1$residuals)
## 
##  Shapiro-Wilk normality test
## 
## data:  mod1$residuals
## W = 0.99101, p-value = 0.02772
plot(mod1, which=3) # Passes homogeneity of variance assumption (roughly horizontal through with random pattern)

# Assumptions failed

# Check assumptions:
plot(modlog1, which=2) # passes normality assumption

shapiro.test(modlog1$residuals)
## 
##  Shapiro-Wilk normality test
## 
## data:  modlog1$residuals
## W = 0.99718, p-value = 0.7962
plot(modlog1, which=3) # passes homogeneity assumption

# Assumptions pass

# 2: Wing Length

# Check assumptions (mod2)
plot(mod2, which=2) # Fails 

shapiro.test((mod2$residuals))
## 
##  Shapiro-Wilk normality test
## 
## data:  (mod2$residuals)
## W = 0.99052, p-value = 0.02054
plot(mod2, which=3) # Passes homogeneity of variance assumptions

# Assumptions fail

# Normality assumptions (modlog2)
plot(modlog2, which = 2) # Passes normality

shapiro.test(modlog2$residuals)
## 
##  Shapiro-Wilk normality test
## 
## data:  modlog2$residuals
## W = 0.99251, p-value = 0.06866
plot(modlog2, which=3) # Passes homogeneity of variance assumption

# Assumptions fails

# Check assumptions (modglm2)
plot(simulateResiduals(modglm2))

# Fails normality assumptions but best-looking diagnostic plots

Figure(s)

# ggplot 1 (Body Mass)
plot1 = ggplot(data=mod1, aes(x=urbanization, y=body.mass, color=sex)) +
  geom_point() +
  geom_smooth(method = "lm", se=TRUE) +
  scale_color_manual(values=c("red","blue")) +
  theme(plot.title = element_text(hjust=0.5)) + # Center title
  theme(title=element_text(size=8)) + # Font size
  theme(title=element_text(face="bold")) + # Font bold
  ggtitle("Sex and Urbanization on Body Mass") + # Creating title
  labs(x="Urbanization (%)", y= "Body Mass (g)", color = "Sex") # Label axis

# ggplot 2 (Wing Length)
plot2 = ggplot(data=modglm2, aes(x=urbanization, y=wing.length, color=sex)) +
  geom_point() +
  geom_smooth(method = "lm", se=TRUE) +
  scale_color_manual(values=c("red","blue")) +
  theme(plot.title = element_text(hjust=0.5)) + # Center title
  theme(title=element_text(size=8)) + # Font size
  theme(title=element_text(face="bold")) + # Bond font
  ggtitle("Sex and Urbanization on Wing Length") + # Creates titles
  labs(x="Urbanization (%)", y= "Wing Length(mm)", color="Sex") # Label axis

# Side-by-side ggplot
plot_grid(plot1, plot2, labels = "AUTO") # Plot the graphs side-by-side
## `geom_smooth()` using formula = 'y ~ x'
## `geom_smooth()` using formula = 'y ~ x'

Interpretation


In this analysis, I fitted two separate models as a proxy for body size of barn swallows with urbanization and sex as explanatory variables for both models: I wanted to explore whether an interaction term existed between the explanatory variables. Based on the graphs made, there is no significant interaction term between “Urbanization” and “Sex” highlighted by their parallelism in regression lines. Our Anova function netted that individual effects of A (Urbanization) and B(Sex) are statistically significant (p<0.05), while A:B interaction was nonsignificant (p>0.05). This suggests that our response is dependent on variables A and B effects but not their joint effects.

Overall, the interpretation of our analysis is that urbanization has an inverse relationship with body size (mass or wing length): Females are bigger in body mass (g) on average compared to males, and males have longer wing lengths(mm) on average compared to females. The statistical significance of urbanization and sex bsuggests there’s statistically significant differences in body size in each group of urbanization and sex, and interaction suggests that each variable contributes to variation in body size but not to the other variable’s effects on body size.

Seeing as that body size declines with increasing urbanization, this could be an adaptation of the swallow to fit in a metropolis. If there are more buildings/structures, then there are less trees/houses that swallows are able to nest on. This is especially more possible given that skyscrapers occupy a good portion of a metropolis at a height unsuitable for nesting so being lighter/smaller is advantageous for living in decorative trees: the Southern region of China is great for farming with its warm climate, , so swallows have a good source of food and home. Thus, maybe they have more resources to direct to development.

The limitations of my interpretations is that wing length data deviates from normality assumptions, so our analysis of the data we’ve interpreted could be flawed. Another caveat of our interpretation is that it doesn’t include certain confounding variables that could be correlated: Bergmann’s rule explains animals adopt larger frames in colder regions.

Connection back to biological question: No, we can establish that there are no effects of sex on urbanization’s effect on body size as there is no interaction term (lines are parallel).

ANALYSIS 2

Question & hypotheses

Biological question

  • State the biological question(s) that this analysis is addressing.

Do swallows North of Beijing have larger body mass compared to swallows South of Beijing? — Controlling for the effects of urbanization

Statistical analysis

  • Describe the linear model you will use to address your biological question(s): list the response and explanatory variables in your model, including interactions if applicable.

The linear model will simply be selecting for groups of sparrows above and below a certain latitude references around a center point of Beijing. The linear model will have body mass as the response variable and latitude as th explanatory variable while controlling for urbanization.

Analysis & figure(s)

Analysis

Run the analysis

# Run packages
library(tidyverse)
library(emmeans)
library(car)
library(effectsize)

# Set contrasts
options(contrasts=c("contr.poly", "contr.sum"))

# Import the dataset:
# Code to import a dataset
BodySize_data <- read.csv("/Users/winny/Downloads/doi_10-10/Liu_Winson Dataset/BodySize_data.csv", stringsAsFactors=TRUE)

# Do Swallows North of Beijing have larger body mass than swallows South of Beijing?

# Create latitude variable
BodySize_data$direction = ifelse(BodySize_data$latitude > 39.82022, "North", "South")
# Remove Beijing and associated data
Swallows_direction <- filter(BodySize_data, city != "Beijing")

# Missing value check
is.na(Swallows_direction$direction)
##   [1] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
##  [13] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
##  [25] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
##  [37] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
##  [49] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
##  [61] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
##  [73] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
##  [85] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
##  [97] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
## [109] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
## [121] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
## [133] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
## [145] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
## [157] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
## [169] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
## [181] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
## [193] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
## [205] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
## [217] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
## [229] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
## [241] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
## [253] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
## [265] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
## [277] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
## [289] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
## [301] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
## [313] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
## [325] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
## [337] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
# Fit model
mod3 = lm(body.mass ~ direction + urbanization, data=Swallows_direction)

# Refit model (log-transform) - Most normal
modlog3 = lm(log(body.mass)~direction+urbanization, data=Swallows_direction)

# Refit model (GLM)
modglm3 = glm(body.mass~direction+urbanization, data=Swallows_direction, family="Gamma")

# emmeans
emmeans(modlog3, specs="direction")
##  direction emmean       SE  df lower.CL upper.CL
##  North      2.753 0.007013 344    2.739    2.767
##  South      2.785 0.008323 344    2.768    2.801
## 
## Results are given on the log (not the response) scale. 
## Confidence level used: 0.95
emm.swallow = emmeans(modlog3, specs="direction") %>% as.data.frame()

# Analysis
# Anova
Anova(modlog3, type=3) # P-value statistically significant
## Anova Table (Type III tests)
## 
## Response: log(body.mass)
##              Sum Sq  Df    F value    Pr(>F)    
## (Intercept)  830.33   1 98351.8568 < 2.2e-16 ***
## direction      0.06   1     7.3457  0.007059 ** 
## urbanization   0.09   1    10.5566  0.001272 ** 
## Residuals      2.90 344                         
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
# R^2
summary(modlog3)
## 
## Call:
## lm(formula = log(body.mass) ~ direction + urbanization, data = Swallows_direction)
## 
## Residuals:
##      Min       1Q   Median       3Q      Max 
## -0.25506 -0.06628 -0.01066  0.05730  0.30741 
## 
## Coefficients:
##                Estimate Std. Error t value Pr(>|t|)    
## (Intercept)   2.7942936  0.0089101 313.611  < 2e-16 ***
## direction.L   0.0224021  0.0082656   2.710  0.00706 ** 
## urbanization -0.0004515  0.0001390  -3.249  0.00127 ** 
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 0.09188 on 344 degrees of freedom
## Multiple R-squared:  0.09761,    Adjusted R-squared:  0.09237 
## F-statistic: 18.61 on 2 and 344 DF,  p-value: 2.126e-08
# Effect size
emmeans(modlog3, specs="direction") %>% 
  eff_size(sigma=sigma(modlog3), edf=df.residual(modlog3)) 
##  contrast      effect.size    SE  df lower.CL upper.CL
##  North - South      -0.345 0.128 344   -0.596  -0.0932
## 
## sigma used for effect sizes: 0.09188 
## Confidence level used: 0.95
# eta squared
eta_squared(modlog3, partial=F)
## # Effect Size for ANOVA (Type I)
## 
## Parameter    | Eta2 |       95% CI
## ----------------------------------
## direction    | 0.07 | [0.03, 1.00]
## urbanization | 0.03 | [0.01, 1.00]
## 
## - One-sided CIs: upper bound fixed at [1.00].
# partial eta squared
eta_squared(modlog3, partial=T)
## # Effect Size for ANOVA (Type I)
## 
## Parameter    | Eta2 (partial) |       95% CI
## --------------------------------------------
## direction    |           0.07 | [0.03, 1.00]
## urbanization |           0.03 | [0.01, 1.00]
## 
## - One-sided CIs: upper bound fixed at [1.00].

Check assumptions

# Check assumptions (mod1)
plot(mod3, which=2) # Fails normality assumptions

shapiro.test(mod3$residuals)
## 
##  Shapiro-Wilk normality test
## 
## data:  mod3$residuals
## W = 0.96631, p-value = 3.445e-07
plot(mod3, which=3) # Passes homogeneity of variance assumption

# Assumptions fail

# Check assumptions (modlog1) - Go with this one
plot(modlog3, which=2) # Fails normality

shapiro.test(modlog3$residuals)
## 
##  Shapiro-Wilk normality test
## 
## data:  modlog3$residuals
## W = 0.98322, p-value = 0.0004551
plot(modlog3, which=3) # Heterogeneity starts wavering

# Assumptions ALSO fail, but it's the best we got.

# Check assumptions (modglm1)
plot(modglm3, which=2) # Fails normality

shapiro.test(modglm3$residuals)
## 
##  Shapiro-Wilk normality test
## 
## data:  modglm3$residuals
## W = 0.962, p-value = 7.655e-08
plot(modglm3, which=3) # Passes heterogeneity

# Assumptions fail

# With this, I've exhausted all the possible tests that we've discussed in this course. The most normal lm is log-transformed, so we'll proceed with that.

Figure(s)

# ggplot
ggplot() +
  geom_jitter(data=Swallows_direction, aes(x=direction, y=body.mass, color=direction)) +
  geom_point(data=emm.swallow, aes(x=direction, y=exp(emmean)), color="purple", size=3) +
  geom_errorbar(data=emm.swallow, aes(x=direction, ymin=exp(lower.CL), ymax=exp(upper.CL)), width=0.2) +
  theme(legend.position = "none") +
  theme(plot.title = element_text(hjust=0.5)) + # Center title
  theme(title=element_text(size=8)) + # Font size
  theme(title=element_text(face="bold")) + # Font bold
  ggtitle("Body Size in Swallows: North vs South") + # Creating title
  labs(x="Direction", y= "Body Mass (g)")# Label axis 

Interpretation

In this analysis, I fit three separate models. None of these models were able to completely pass assumption checks, so I utilized the “most” correct model (modlog2) for my analysis. Connecting back to my biological question, there is a statistically significant difference (p<0.05) in body mass between swallows in the Northern regions vs swallows in the Southern region. However, my biological question was made with Bergmann’s rule in mind; the Southern region actually had a greater average, statistically significant, body mass in grams.

As stated above, my model failed assumptions, so I selected the best-fit model to these assumptions. There is the possibility that I used the wrong GLM.

My figure accurate represents the results of my ANOVA. If you use the eyeball test of confidence intervals, you can see that the confidence intervals do not overlap, suggesting a statistically significant result. If you argue that the confidence intervals do overlap, you’d do the analysis to find the results are signficant: the confidence intervals do not overlap the mean!

Ultimately, my biological question failed, but I managed to get a result that suggested that one region of China had greater body mass (Southern). However, I managed to describe significance, but what is the magnitude of this significance? I ran effect size tests and found Cohen’s D effect size to be -0.345 contrast North - South; eta squared of direction is 7%. These results suggest to me that although our results are statistically significant, there is no practical application to this signficance since our effect size values are so small that it makes no sense in a biological context.

If I were to make a reasoning behind my graphed results despite the low effect size, I would say some variable holds more weight than the effectors in Bergmann’s rule: something in the Southern region of China is causing average body mass to be bigger, despite a warmer climate.

There are some obvious limitations of my interpretation. The first is that since our assumptions failed, then our analysis could be biased. Another is my decision to classify regions of China. I wanted a fair representation to begin with my data, so I made Beijing my center point and everything above and below is filtered as a certain region.

The issue with this classification is that it doesn’t establish the proximity of these cities. Some of these cities are actually part of central China, and some of these cities are port cities. There’s too much diversification, and my degrees of freedom in formatting the data could’ve made my results biased.

LS0tCnRpdGxlOiAnQklPTCA0NTExLzU1MTE6IEZpbmFsIFByb2plY3QnCmF1dGhvcjogIldpbnNvbiBMaXUiCm91dHB1dDoKICBodG1sX2RvY3VtZW50OgogICAgY29kZV9kb3dubG9hZDogdHJ1ZQogICAgdG9jOiB5ZXMKICAgIHRvY19kZXB0aDogNAogICAgdG9jX2Zsb2F0OiB5ZXMKICAgIHRoZW1lOiBjZXJ1bGVhbgogIHBkZl9kb2N1bWVudDoKICAgIHRvYzogeWVzCiAgICB0b2NfZGVwdGg6ICc0JwotLS0KCiMgSW50cm9kdWN0aW9uCgotICAgKkJyaWVmbHkgKFx+MSBwYXJhZ3JhcGgpIGRlc2NyaWJlIHRoZSBnb2FsIG9mIHRoZSBzdHVkeSwgdGhlIGV4cGVyaW1lbnRhbCBkZXNpZ24sIHRoZSB1bml0IG9mIG9ic2VydmF0aW9uLCBhbmQgYW55IHJlbGV2YW50IG1ldGhvZHMuKgoKVGhlIGdvYWwgb2YgdGhlIHN0dWR5IGlzIHRvIGludmVzdGlnYXRlIHRoZSBlZmZlY3RzIG9mIGhpZ2gtc2NhbGUgdXJiYW5pemF0aW9uIG9uIHRoZSBib2R5IHNpemUgb2YgQmFybiBTd2FsbG93cyAqSGlydW5kbyBydXN0aWNhIGd1dHR1cmFsaXMqIGluIENoaW5hLiBUaGlzIHN0dWR5IGlzIHBhcnRpY3VsYXJseSBpbnRlcmVzdGluZyBhcyBpdCBhZGRyZXNzZXMgdGhlc2UgZWZmZWN0cyBpbiByZWdhcmRzIHRvIFN3YWxsb3dzIG9mIGRpZmZlcmVudCBlbnZpcm9ubWVudGFsIGFuZCBjbGltYXRlIG9yaWdpbnMuIFRoZSBkZXNpZ24gb2YgdGhlIGV4cGVyaW1lbnQgd2FzIHRvIGNvbGxlY3QgcGh5c2lvbG9naWNhbCBkYXRhIChib2R5IG1hc3MgYW5kIHdpbmcgbGVuZ3RoKSBvZiBicmVlZGluZyBpbmRpdmlkdWFscyBmcm9tIDEyOCBzaXRlcyBhdCB2YXJ5aW5nIHN0YWdlcyBvZiB1cmJhbml6YXRpb24gYWNyb3NzIENoaW5hLiBUaGUgdW5pdCBvZiBvYnNlcnZhdGlvbiBpcyBhIHNpbmd1bGFyIHN3YWxsb3cuCgo8YnI+CgojIEFOQUxZU0lTIDEKCiMjIFF1ZXN0aW9uICYgaHlwb3RoZXNlcwoKIyMjIEJpb2xvZ2ljYWwgcXVlc3Rpb24KCi0gICAqU3RhdGUgdGhlICoqYmlvbG9naWNhbCBxdWVzdGlvbihzKSoqIHRoYXQgdGhpcyBhbmFseXNpcyBpcyBhZGRyZXNzaW5nLioKCkRvZXMgdXJiYW5pemF0aW9uIGFmZmVjdCBib2R5IHNpemUgZGlmZmVyZW50bHkgYmV0d2VlbiBkaWZmZXJlbnQgc2V4ZXM/CgojIyMgU3RhdGlzdGljYWwgYW5hbHlzaXMKCi0gICAqRGVzY3JpYmUgdGhlICoqbGluZWFyIG1vZGVsKiogeW91IHdpbGwgdXNlIHRvIGFkZHJlc3MgeW91ciBiaW9sb2dpY2FsIHF1ZXN0aW9uKHMpOiBsaXN0IHRoZSByZXNwb25zZSBhbmQgZXhwbGFuYXRvcnkgdmFyaWFibGVzIGluIHlvdXIgbW9kZWwsIGluY2x1ZGluZyBpbnRlcmFjdGlvbnMgaWYgYXBwbGljYWJsZS4qCgpJbmRlcGVuZGVudCB2YXJpYWJsZXMgd2lsbCBiZSAoMSkgVXJiYW5pemF0aW9uIGFuZCAoMikgU2V4LiBJIHdpbGwgZml0IDIgZGlmZmVyZW50IG1vZGVscyAoYm9keSBtYXNzIGFuZCB3aW5nIGxlbmd0aCBhcyByZXNwb25zZSB2YXJpYWJsZXMpLiBBTk9WQSwgUmVncmVzc2lvbiwgQXNzdW1wdGlvbiB0ZXN0cyAoZGF0YSBpcyBwcm9iYWJseSBub3Qgbm9ybWFsLCBzbyBsb2cgdHJhbnNmb3JtYXRpb25zLikgSW4gb3JkZXIgdG8gYW5zd2VyIG15IGJpb2xvZ2ljYWwgcXVlc3Rpb24sIEkgbmVlZCB0byBpbmNsdWRlIGFuIGludGVyYWN0aW9uIHRlcm0gYmV0d2VlbiB1cmJhbml6YXRpb24gYW5kIHNleC4KCiMjIEFuYWx5c2lzICYgZmlndXJlKHMpCgojIyMgQW5hbHlzaXMKCiMjIyMgUnVuIHRoZSBhbmFseXNpcwoKYGBge3J9CiMgTG9hZCBwYWNrYWdlcwpsaWJyYXJ5KHRpZHl2ZXJzZSkKbGlicmFyeShjYXIpCmxpYnJhcnkoY293cGxvdCkKbGlicmFyeShlbW1lYW5zKQpsaWJyYXJ5KERIQVJNYSkKCiMgU2V0IGNvbnRyYXN0cwpvcHRpb25zKGNvbnRyYXN0cz1jKCJjb250ci5wb2x5IiwiY29udHIuc3VtIikpCgojIEltcG9ydCB0aGUgZGF0YXNldDoKIyBDb2RlIHRvIGltcG9ydCBhIGRhdGFzZXQKQm9keVNpemVfZGF0YSA8LSByZWFkLmNzdigiL1VzZXJzL3dpbm55L0Rvd25sb2Fkcy9kb2lfMTAtMTAvTGl1X1dpbnNvbiBEYXRhc2V0L0JvZHlTaXplX2RhdGEuY3N2Iiwgc3RyaW5nc0FzRmFjdG9ycz1UUlVFKQoKIyBEb2VzIHVyYmFuaXphdGlvbiBhZmZlY3QgYm9keSBzaXplIFtCb2R5IG1hc3MgLyBXaW5nIGxlbmd0aF0gZGlmZmVyZW50bHkgYmV0d2VlbiBkaWZmZXJlbnQgc2V4ZXM/CgojIENoZWNrIGZvciBtaXNzaW5nIHZhbHVlcwppcy5uYShCb2R5U2l6ZV9kYXRhJHNleCkKaXMubmEoQm9keVNpemVfZGF0YSR1cmJhbml6YXRpb24pCmlzLm5hKEJvZHlTaXplX2RhdGEkYm9keS5tYXNzKQppcy5uYShCb2R5U2l6ZV9kYXRhJHdpbmcubGVuZ3RoKQoKIyBGaXQgdGhlIG1vZGVsOiAoYm9keSBtYXNzKQojIEFzc3VtcHRpb25zIGZhaWxlZAptb2QxID0gbG0oYm9keS5tYXNzIH4gdXJiYW5pemF0aW9uICogc2V4LCBkYXRhPUJvZHlTaXplX2RhdGEpCgojIEFzc3VtcHRpb25zIHBhc3NlZAptb2Rsb2cxID0gbG0obG9nKGJvZHkubWFzcykgfiB1cmJhbml6YXRpb24qc2V4LCBkYXRhPUJvZHlTaXplX2RhdGEpCgojIEFuYWx5c2lzCiMgQW5vdmEKQW5vdmEobW9kbG9nMSwgdHlwZT0zKQojIFN1bW1hcnkKc3VtbWFyeShtb2Rsb2cxKQoKIyBGaXQgdGhlIG1vZGVsIDI6ICh3aW5nIGxlbmd0aCkKIyBBc3N1bXB0aW9ucyBmYWlsZWQKbW9kMiA9IGxtKHdpbmcubGVuZ3RoIH4gdXJiYW5pemF0aW9uICogc2V4LCBkYXRhPUJvZHlTaXplX2RhdGEpCgojIEFzc3VtcHRpb25zIGZhaWxlZAptb2Rsb2cyID0gbG0obG9nKHdpbmcubGVuZ3RoKSB+IHVyYmFuaXphdGlvbiAqIHNleCwgZGF0YT1Cb2R5U2l6ZV9kYXRhKQoKbW9kZ2xtMiA9IGdsbSh3aW5nLmxlbmd0aCB+IHVyYmFuaXphdGlvbipzZXgsIGRhdGE9Qm9keVNpemVfZGF0YSwgZmFtaWx5PSJHYW1tYSIpCgojIEFuYWx5c2lzCiMgQW5vdmEKQW5vdmEobW9kZ2xtMiwgdHlwZT0zKQoKIyBTdW1tYXJ5CnN1bW1hcnkobW9kZ2xtMikKYGBgCgojIyMjIENoZWNrIGFzc3VtcHRpb25zCgpgYGB7cn0KIyAxOiBCb2R5IE1hc3MKIyBDaGVjayBhc3N1bXB0aW9ucyAobW9kMSkKcGxvdChtb2QxLCB3aGljaD0yKSAjIEZhaWxzIG5vcm1hbGl0eSBhc3N1bXB0aW9ucwpzaGFwaXJvLnRlc3QobW9kMSRyZXNpZHVhbHMpCnBsb3QobW9kMSwgd2hpY2g9MykgIyBQYXNzZXMgaG9tb2dlbmVpdHkgb2YgdmFyaWFuY2UgYXNzdW1wdGlvbiAocm91Z2hseSBob3Jpem9udGFsIHRocm91Z2ggd2l0aCByYW5kb20gcGF0dGVybikKCiMgQXNzdW1wdGlvbnMgZmFpbGVkCgojIENoZWNrIGFzc3VtcHRpb25zOgpwbG90KG1vZGxvZzEsIHdoaWNoPTIpICMgcGFzc2VzIG5vcm1hbGl0eSBhc3N1bXB0aW9uCnNoYXBpcm8udGVzdChtb2Rsb2cxJHJlc2lkdWFscykKcGxvdChtb2Rsb2cxLCB3aGljaD0zKSAjIHBhc3NlcyBob21vZ2VuZWl0eSBhc3N1bXB0aW9uCgojIEFzc3VtcHRpb25zIHBhc3MKCiMgMjogV2luZyBMZW5ndGgKCiMgQ2hlY2sgYXNzdW1wdGlvbnMgKG1vZDIpCnBsb3QobW9kMiwgd2hpY2g9MikgIyBGYWlscyAKc2hhcGlyby50ZXN0KChtb2QyJHJlc2lkdWFscykpCnBsb3QobW9kMiwgd2hpY2g9MykgIyBQYXNzZXMgaG9tb2dlbmVpdHkgb2YgdmFyaWFuY2UgYXNzdW1wdGlvbnMKIyBBc3N1bXB0aW9ucyBmYWlsCgojIE5vcm1hbGl0eSBhc3N1bXB0aW9ucyAobW9kbG9nMikKcGxvdChtb2Rsb2cyLCB3aGljaCA9IDIpICMgUGFzc2VzIG5vcm1hbGl0eQpzaGFwaXJvLnRlc3QobW9kbG9nMiRyZXNpZHVhbHMpCnBsb3QobW9kbG9nMiwgd2hpY2g9MykgIyBQYXNzZXMgaG9tb2dlbmVpdHkgb2YgdmFyaWFuY2UgYXNzdW1wdGlvbgojIEFzc3VtcHRpb25zIGZhaWxzCgojIENoZWNrIGFzc3VtcHRpb25zIChtb2RnbG0yKQpwbG90KHNpbXVsYXRlUmVzaWR1YWxzKG1vZGdsbTIpKQojIEZhaWxzIG5vcm1hbGl0eSBhc3N1bXB0aW9ucyBidXQgYmVzdC1sb29raW5nIGRpYWdub3N0aWMgcGxvdHMKYGBgCgojIyMgRmlndXJlKHMpCgpgYGB7cn0KIyBnZ3Bsb3QgMSAoQm9keSBNYXNzKQpwbG90MSA9IGdncGxvdChkYXRhPW1vZDEsIGFlcyh4PXVyYmFuaXphdGlvbiwgeT1ib2R5Lm1hc3MsIGNvbG9yPXNleCkpICsKICBnZW9tX3BvaW50KCkgKwogIGdlb21fc21vb3RoKG1ldGhvZCA9ICJsbSIsIHNlPVRSVUUpICsKICBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzPWMoInJlZCIsImJsdWUiKSkgKwogIHRoZW1lKHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoaGp1c3Q9MC41KSkgKyAjIENlbnRlciB0aXRsZQogIHRoZW1lKHRpdGxlPWVsZW1lbnRfdGV4dChzaXplPTgpKSArICMgRm9udCBzaXplCiAgdGhlbWUodGl0bGU9ZWxlbWVudF90ZXh0KGZhY2U9ImJvbGQiKSkgKyAjIEZvbnQgYm9sZAogIGdndGl0bGUoIlNleCBhbmQgVXJiYW5pemF0aW9uIG9uIEJvZHkgTWFzcyIpICsgIyBDcmVhdGluZyB0aXRsZQogIGxhYnMoeD0iVXJiYW5pemF0aW9uICglKSIsIHk9ICJCb2R5IE1hc3MgKGcpIiwgY29sb3IgPSAiU2V4IikgIyBMYWJlbCBheGlzCgojIGdncGxvdCAyIChXaW5nIExlbmd0aCkKcGxvdDIgPSBnZ3Bsb3QoZGF0YT1tb2RnbG0yLCBhZXMoeD11cmJhbml6YXRpb24sIHk9d2luZy5sZW5ndGgsIGNvbG9yPXNleCkpICsKICBnZW9tX3BvaW50KCkgKwogIGdlb21fc21vb3RoKG1ldGhvZCA9ICJsbSIsIHNlPVRSVUUpICsKICBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzPWMoInJlZCIsImJsdWUiKSkgKwogIHRoZW1lKHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoaGp1c3Q9MC41KSkgKyAjIENlbnRlciB0aXRsZQogIHRoZW1lKHRpdGxlPWVsZW1lbnRfdGV4dChzaXplPTgpKSArICMgRm9udCBzaXplCiAgdGhlbWUodGl0bGU9ZWxlbWVudF90ZXh0KGZhY2U9ImJvbGQiKSkgKyAjIEJvbmQgZm9udAogIGdndGl0bGUoIlNleCBhbmQgVXJiYW5pemF0aW9uIG9uIFdpbmcgTGVuZ3RoIikgKyAjIENyZWF0ZXMgdGl0bGVzCiAgbGFicyh4PSJVcmJhbml6YXRpb24gKCUpIiwgeT0gIldpbmcgTGVuZ3RoKG1tKSIsIGNvbG9yPSJTZXgiKSAjIExhYmVsIGF4aXMKCiMgU2lkZS1ieS1zaWRlIGdncGxvdApwbG90X2dyaWQocGxvdDEsIHBsb3QyLCBsYWJlbHMgPSAiQVVUTyIpICMgUGxvdCB0aGUgZ3JhcGhzIHNpZGUtYnktc2lkZQpgYGAKCiMjIEludGVycHJldGF0aW9uCgo8YnI+ICoqSW4gdGhpcyBhbmFseXNpcywgSSBmaXR0ZWQgdHdvIHNlcGFyYXRlIG1vZGVscyBhcyBhIHByb3h5IGZvciBib2R5IHNpemUgb2YgYmFybiBzd2FsbG93cyB3aXRoIHVyYmFuaXphdGlvbiBhbmQgc2V4IGFzIGV4cGxhbmF0b3J5IHZhcmlhYmxlcyBmb3IgYm90aCBtb2RlbHM6IEkgd2FudGVkIHRvIGV4cGxvcmUgd2hldGhlciBhbiBpbnRlcmFjdGlvbiB0ZXJtIGV4aXN0ZWQgYmV0d2VlbiB0aGUgZXhwbGFuYXRvcnkgdmFyaWFibGVzLiBCYXNlZCBvbiB0aGUgZ3JhcGhzIG1hZGUsIHRoZXJlIGlzIG5vIHNpZ25pZmljYW50IGludGVyYWN0aW9uIHRlcm0gYmV0d2VlbiAiVXJiYW5pemF0aW9uIiBhbmQgIlNleCIgaGlnaGxpZ2h0ZWQgYnkgdGhlaXIgcGFyYWxsZWxpc20gaW4gcmVncmVzc2lvbiBsaW5lcy4gT3VyIEFub3ZhIGZ1bmN0aW9uIG5ldHRlZCB0aGF0IGluZGl2aWR1YWwgZWZmZWN0cyBvZiBBIChVcmJhbml6YXRpb24pIGFuZCBCKFNleCkgYXJlIHN0YXRpc3RpY2FsbHkgc2lnbmlmaWNhbnQgKHA8MC4wNSksIHdoaWxlIEE6QiBpbnRlcmFjdGlvbiB3YXMgbm9uc2lnbmlmaWNhbnQgKHA+MC4wNSkuIFRoaXMgc3VnZ2VzdHMgdGhhdCBvdXIgcmVzcG9uc2UgaXMgZGVwZW5kZW50IG9uIHZhcmlhYmxlcyBBIGFuZCBCIGVmZmVjdHMgYnV0IG5vdCB0aGVpciBqb2ludCBlZmZlY3RzLioqCgoqKk92ZXJhbGwsIHRoZSBpbnRlcnByZXRhdGlvbiBvZiBvdXIgYW5hbHlzaXMgaXMgdGhhdCB1cmJhbml6YXRpb24gaGFzIGFuIGludmVyc2UgcmVsYXRpb25zaGlwIHdpdGggYm9keSBzaXplIChtYXNzIG9yIHdpbmcgbGVuZ3RoKTogRmVtYWxlcyBhcmUgYmlnZ2VyIGluIGJvZHkgbWFzcyAoZykgb24gYXZlcmFnZSBjb21wYXJlZCB0byBtYWxlcywgYW5kIG1hbGVzIGhhdmUgbG9uZ2VyIHdpbmcgbGVuZ3RocyhtbSkgb24gYXZlcmFnZSBjb21wYXJlZCB0byBmZW1hbGVzLiBUaGUgc3RhdGlzdGljYWwgc2lnbmlmaWNhbmNlIG9mIHVyYmFuaXphdGlvbiBhbmQgc2V4IGJzdWdnZXN0cyB0aGVyZSdzIHN0YXRpc3RpY2FsbHkgc2lnbmlmaWNhbnQgZGlmZmVyZW5jZXMgaW4gYm9keSBzaXplIGluIGVhY2ggZ3JvdXAgb2YgdXJiYW5pemF0aW9uIGFuZCBzZXgsIGFuZCBpbnRlcmFjdGlvbiBzdWdnZXN0cyB0aGF0IGVhY2ggdmFyaWFibGUgY29udHJpYnV0ZXMgdG8gdmFyaWF0aW9uIGluIGJvZHkgc2l6ZSBidXQgbm90IHRvIHRoZSBvdGhlciB2YXJpYWJsZSdzIGVmZmVjdHMgb24gYm9keSBzaXplLioqCgoqKlNlZWluZyBhcyB0aGF0IGJvZHkgc2l6ZSBkZWNsaW5lcyB3aXRoIGluY3JlYXNpbmcgdXJiYW5pemF0aW9uLCB0aGlzIGNvdWxkIGJlIGFuIGFkYXB0YXRpb24gb2YgdGhlIHN3YWxsb3cgdG8gZml0IGluIGEgbWV0cm9wb2xpcy4gSWYgdGhlcmUgYXJlIG1vcmUgYnVpbGRpbmdzL3N0cnVjdHVyZXMsIHRoZW4gdGhlcmUgYXJlIGxlc3MgdHJlZXMvaG91c2VzIHRoYXQgc3dhbGxvd3MgYXJlIGFibGUgdG8gbmVzdCBvbi4gVGhpcyBpcyBlc3BlY2lhbGx5IG1vcmUgcG9zc2libGUgZ2l2ZW4gdGhhdCBza3lzY3JhcGVycyBvY2N1cHkgYSBnb29kIHBvcnRpb24gb2YgYSBtZXRyb3BvbGlzIGF0IGEgaGVpZ2h0IHVuc3VpdGFibGUgZm9yIG5lc3Rpbmcgc28gYmVpbmcgbGlnaHRlci9zbWFsbGVyIGlzIGFkdmFudGFnZW91cyBmb3IgbGl2aW5nIGluIGRlY29yYXRpdmUgdHJlZXM6IHRoZSBTb3V0aGVybiByZWdpb24gb2YgQ2hpbmEgaXMgZ3JlYXQgZm9yIGZhcm1pbmcgd2l0aCBpdHMgd2FybSBjbGltYXRlLCAsIHNvIHN3YWxsb3dzIGhhdmUgYSBnb29kIHNvdXJjZSBvZiBmb29kIGFuZCBob21lLiBUaHVzLCBtYXliZSB0aGV5IGhhdmUgbW9yZSByZXNvdXJjZXMgdG8gZGlyZWN0IHRvIGRldmVsb3BtZW50LioqCgoqKlRoZSBsaW1pdGF0aW9ucyBvZiBteSBpbnRlcnByZXRhdGlvbnMgaXMgdGhhdCB3aW5nIGxlbmd0aCBkYXRhIGRldmlhdGVzIGZyb20gbm9ybWFsaXR5IGFzc3VtcHRpb25zLCBzbyBvdXIgYW5hbHlzaXMgb2YgdGhlIGRhdGEgd2UndmUgaW50ZXJwcmV0ZWQgY291bGQgYmUgZmxhd2VkLiBBbm90aGVyIGNhdmVhdCBvZiBvdXIgaW50ZXJwcmV0YXRpb24gaXMgdGhhdCBpdCBkb2Vzbid0IGluY2x1ZGUgY2VydGFpbiBjb25mb3VuZGluZyB2YXJpYWJsZXMgdGhhdCBjb3VsZCBiZSBjb3JyZWxhdGVkOiBCZXJnbWFubidzIHJ1bGUgZXhwbGFpbnMgYW5pbWFscyBhZG9wdCBsYXJnZXIgZnJhbWVzIGluIGNvbGRlciByZWdpb25zLioqCgoqKkNvbm5lY3Rpb24gYmFjayB0byBiaW9sb2dpY2FsIHF1ZXN0aW9uOiBObywgd2UgY2FuIGVzdGFibGlzaCB0aGF0IHRoZXJlIGFyZSBubyBlZmZlY3RzIG9mIHNleCBvbiB1cmJhbml6YXRpb24ncyBlZmZlY3Qgb24gYm9keSBzaXplIGFzIHRoZXJlIGlzIG5vIGludGVyYWN0aW9uIHRlcm0gKGxpbmVzIGFyZSBwYXJhbGxlbCkuKiogCgojIEFOQUxZU0lTIDIKCiMjIFF1ZXN0aW9uICYgaHlwb3RoZXNlcwoKIyMjIEJpb2xvZ2ljYWwgcXVlc3Rpb24KCi0gICAqU3RhdGUgdGhlICoqYmlvbG9naWNhbCBxdWVzdGlvbihzKSoqIHRoYXQgdGhpcyBhbmFseXNpcyBpcyBhZGRyZXNzaW5nLioKCkRvIHN3YWxsb3dzIE5vcnRoIG9mIEJlaWppbmcgaGF2ZSBsYXJnZXIgYm9keSBtYXNzIGNvbXBhcmVkIHRvIHN3YWxsb3dzIFNvdXRoIG9mIEJlaWppbmc/IOKAlCBDb250cm9sbGluZyBmb3IgdGhlIGVmZmVjdHMgb2YgdXJiYW5pemF0aW9uCgojIyMgU3RhdGlzdGljYWwgYW5hbHlzaXMKCi0gICAqRGVzY3JpYmUgdGhlICoqbGluZWFyIG1vZGVsKiogeW91IHdpbGwgdXNlIHRvIGFkZHJlc3MgeW91ciBiaW9sb2dpY2FsIHF1ZXN0aW9uKHMpOiBsaXN0IHRoZSByZXNwb25zZSBhbmQgZXhwbGFuYXRvcnkgdmFyaWFibGVzIGluIHlvdXIgbW9kZWwsIGluY2x1ZGluZyBpbnRlcmFjdGlvbnMgaWYgYXBwbGljYWJsZS4qCgpUaGUgbGluZWFyIG1vZGVsIHdpbGwgc2ltcGx5IGJlIHNlbGVjdGluZyBmb3IgZ3JvdXBzIG9mIHNwYXJyb3dzIGFib3ZlIGFuZCBiZWxvdyBhIGNlcnRhaW4gbGF0aXR1ZGUgcmVmZXJlbmNlcyBhcm91bmQgYSBjZW50ZXIgcG9pbnQgb2YgQmVpamluZy4gVGhlIGxpbmVhciBtb2RlbCB3aWxsIGhhdmUgYm9keSBtYXNzIGFzIHRoZSByZXNwb25zZSB2YXJpYWJsZSBhbmQgbGF0aXR1ZGUgYXMgdGggZXhwbGFuYXRvcnkgdmFyaWFibGUgd2hpbGUgY29udHJvbGxpbmcgZm9yIHVyYmFuaXphdGlvbi4KCiMjIEFuYWx5c2lzICYgZmlndXJlKHMpCgojIyMgQW5hbHlzaXMKCiMjIyMgUnVuIHRoZSBhbmFseXNpcwoKYGBge3J9CiMgUnVuIHBhY2thZ2VzCmxpYnJhcnkodGlkeXZlcnNlKQpsaWJyYXJ5KGVtbWVhbnMpCmxpYnJhcnkoY2FyKQpsaWJyYXJ5KGVmZmVjdHNpemUpCgojIFNldCBjb250cmFzdHMKb3B0aW9ucyhjb250cmFzdHM9YygiY29udHIucG9seSIsICJjb250ci5zdW0iKSkKCiMgSW1wb3J0IHRoZSBkYXRhc2V0OgojIENvZGUgdG8gaW1wb3J0IGEgZGF0YXNldApCb2R5U2l6ZV9kYXRhIDwtIHJlYWQuY3N2KCIvVXNlcnMvd2lubnkvRG93bmxvYWRzL2RvaV8xMC0xMC9MaXVfV2luc29uIERhdGFzZXQvQm9keVNpemVfZGF0YS5jc3YiLCBzdHJpbmdzQXNGYWN0b3JzPVRSVUUpCgojIERvIFN3YWxsb3dzIE5vcnRoIG9mIEJlaWppbmcgaGF2ZSBsYXJnZXIgYm9keSBtYXNzIHRoYW4gc3dhbGxvd3MgU291dGggb2YgQmVpamluZz8KCiMgQ3JlYXRlIGxhdGl0dWRlIHZhcmlhYmxlCkJvZHlTaXplX2RhdGEkZGlyZWN0aW9uID0gaWZlbHNlKEJvZHlTaXplX2RhdGEkbGF0aXR1ZGUgPiAzOS44MjAyMiwgIk5vcnRoIiwgIlNvdXRoIikKIyBSZW1vdmUgQmVpamluZyBhbmQgYXNzb2NpYXRlZCBkYXRhClN3YWxsb3dzX2RpcmVjdGlvbiA8LSBmaWx0ZXIoQm9keVNpemVfZGF0YSwgY2l0eSAhPSAiQmVpamluZyIpCgojIE1pc3NpbmcgdmFsdWUgY2hlY2sKaXMubmEoU3dhbGxvd3NfZGlyZWN0aW9uJGRpcmVjdGlvbikKCiMgRml0IG1vZGVsCm1vZDMgPSBsbShib2R5Lm1hc3MgfiBkaXJlY3Rpb24gKyB1cmJhbml6YXRpb24sIGRhdGE9U3dhbGxvd3NfZGlyZWN0aW9uKQoKIyBSZWZpdCBtb2RlbCAobG9nLXRyYW5zZm9ybSkgLSBNb3N0IG5vcm1hbAptb2Rsb2czID0gbG0obG9nKGJvZHkubWFzcyl+ZGlyZWN0aW9uK3VyYmFuaXphdGlvbiwgZGF0YT1Td2FsbG93c19kaXJlY3Rpb24pCgojIFJlZml0IG1vZGVsIChHTE0pCm1vZGdsbTMgPSBnbG0oYm9keS5tYXNzfmRpcmVjdGlvbit1cmJhbml6YXRpb24sIGRhdGE9U3dhbGxvd3NfZGlyZWN0aW9uLCBmYW1pbHk9IkdhbW1hIikKCiMgZW1tZWFucwplbW1lYW5zKG1vZGxvZzMsIHNwZWNzPSJkaXJlY3Rpb24iKQplbW0uc3dhbGxvdyA9IGVtbWVhbnMobW9kbG9nMywgc3BlY3M9ImRpcmVjdGlvbiIpICU+JSBhcy5kYXRhLmZyYW1lKCkKCiMgQW5hbHlzaXMKIyBBbm92YQpBbm92YShtb2Rsb2czLCB0eXBlPTMpICMgUC12YWx1ZSBzdGF0aXN0aWNhbGx5IHNpZ25pZmljYW50CiMgUl4yCnN1bW1hcnkobW9kbG9nMykKIyBFZmZlY3Qgc2l6ZQplbW1lYW5zKG1vZGxvZzMsIHNwZWNzPSJkaXJlY3Rpb24iKSAlPiUgCiAgZWZmX3NpemUoc2lnbWE9c2lnbWEobW9kbG9nMyksIGVkZj1kZi5yZXNpZHVhbChtb2Rsb2czKSkgCgojIGV0YSBzcXVhcmVkCmV0YV9zcXVhcmVkKG1vZGxvZzMsIHBhcnRpYWw9RikKIyBwYXJ0aWFsIGV0YSBzcXVhcmVkCmV0YV9zcXVhcmVkKG1vZGxvZzMsIHBhcnRpYWw9VCkKYGBgCgojIyMjIENoZWNrIGFzc3VtcHRpb25zCgpgYGB7cn0KIyBDaGVjayBhc3N1bXB0aW9ucyAobW9kMSkKcGxvdChtb2QzLCB3aGljaD0yKSAjIEZhaWxzIG5vcm1hbGl0eSBhc3N1bXB0aW9ucwpzaGFwaXJvLnRlc3QobW9kMyRyZXNpZHVhbHMpCnBsb3QobW9kMywgd2hpY2g9MykgIyBQYXNzZXMgaG9tb2dlbmVpdHkgb2YgdmFyaWFuY2UgYXNzdW1wdGlvbgojIEFzc3VtcHRpb25zIGZhaWwKCiMgQ2hlY2sgYXNzdW1wdGlvbnMgKG1vZGxvZzEpIC0gR28gd2l0aCB0aGlzIG9uZQpwbG90KG1vZGxvZzMsIHdoaWNoPTIpICMgRmFpbHMgbm9ybWFsaXR5CnNoYXBpcm8udGVzdChtb2Rsb2czJHJlc2lkdWFscykKcGxvdChtb2Rsb2czLCB3aGljaD0zKSAjIEhldGVyb2dlbmVpdHkgc3RhcnRzIHdhdmVyaW5nCiMgQXNzdW1wdGlvbnMgQUxTTyBmYWlsLCBidXQgaXQncyB0aGUgYmVzdCB3ZSBnb3QuCgojIENoZWNrIGFzc3VtcHRpb25zIChtb2RnbG0xKQpwbG90KG1vZGdsbTMsIHdoaWNoPTIpICMgRmFpbHMgbm9ybWFsaXR5CnNoYXBpcm8udGVzdChtb2RnbG0zJHJlc2lkdWFscykKcGxvdChtb2RnbG0zLCB3aGljaD0zKSAjIFBhc3NlcyBoZXRlcm9nZW5laXR5CiMgQXNzdW1wdGlvbnMgZmFpbAoKIyBXaXRoIHRoaXMsIEkndmUgZXhoYXVzdGVkIGFsbCB0aGUgcG9zc2libGUgdGVzdHMgdGhhdCB3ZSd2ZSBkaXNjdXNzZWQgaW4gdGhpcyBjb3Vyc2UuIFRoZSBtb3N0IG5vcm1hbCBsbSBpcyBsb2ctdHJhbnNmb3JtZWQsIHNvIHdlJ2xsIHByb2NlZWQgd2l0aCB0aGF0LgpgYGAKCiMjIyBGaWd1cmUocykKCmBgYHtyfQojIGdncGxvdApnZ3Bsb3QoKSArCiAgZ2VvbV9qaXR0ZXIoZGF0YT1Td2FsbG93c19kaXJlY3Rpb24sIGFlcyh4PWRpcmVjdGlvbiwgeT1ib2R5Lm1hc3MsIGNvbG9yPWRpcmVjdGlvbikpICsKICBnZW9tX3BvaW50KGRhdGE9ZW1tLnN3YWxsb3csIGFlcyh4PWRpcmVjdGlvbiwgeT1leHAoZW1tZWFuKSksIGNvbG9yPSJwdXJwbGUiLCBzaXplPTMpICsKICBnZW9tX2Vycm9yYmFyKGRhdGE9ZW1tLnN3YWxsb3csIGFlcyh4PWRpcmVjdGlvbiwgeW1pbj1leHAobG93ZXIuQ0wpLCB5bWF4PWV4cCh1cHBlci5DTCkpLCB3aWR0aD0wLjIpICsKICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAibm9uZSIpICsKICB0aGVtZShwbG90LnRpdGxlID0gZWxlbWVudF90ZXh0KGhqdXN0PTAuNSkpICsgIyBDZW50ZXIgdGl0bGUKICB0aGVtZSh0aXRsZT1lbGVtZW50X3RleHQoc2l6ZT04KSkgKyAjIEZvbnQgc2l6ZQogIHRoZW1lKHRpdGxlPWVsZW1lbnRfdGV4dChmYWNlPSJib2xkIikpICsgIyBGb250IGJvbGQKICBnZ3RpdGxlKCJCb2R5IFNpemUgaW4gU3dhbGxvd3M6IE5vcnRoIHZzIFNvdXRoIikgKyAjIENyZWF0aW5nIHRpdGxlCiAgbGFicyh4PSJEaXJlY3Rpb24iLCB5PSAiQm9keSBNYXNzIChnKSIpIyBMYWJlbCBheGlzIApgYGAKCiMjIEludGVycHJldGF0aW9uCioqSW4gdGhpcyBhbmFseXNpcywgSSBmaXQgdGhyZWUgc2VwYXJhdGUgbW9kZWxzLiBOb25lIG9mIHRoZXNlIG1vZGVscyB3ZXJlIGFibGUgdG8gY29tcGxldGVseSBwYXNzIGFzc3VtcHRpb24gY2hlY2tzLCBzbyBJIHV0aWxpemVkIHRoZSAibW9zdCIgY29ycmVjdCBtb2RlbCAobW9kbG9nMikgZm9yIG15IGFuYWx5c2lzLiBDb25uZWN0aW5nIGJhY2sgdG8gbXkgYmlvbG9naWNhbCBxdWVzdGlvbiwgdGhlcmUgaXMgYSBzdGF0aXN0aWNhbGx5IHNpZ25pZmljYW50IGRpZmZlcmVuY2UgKHA8MC4wNSkgaW4gYm9keSBtYXNzIGJldHdlZW4gc3dhbGxvd3MgaW4gdGhlIE5vcnRoZXJuIHJlZ2lvbnMgdnMgc3dhbGxvd3MgaW4gdGhlIFNvdXRoZXJuIHJlZ2lvbi4gSG93ZXZlciwgbXkgYmlvbG9naWNhbCBxdWVzdGlvbiB3YXMgbWFkZSB3aXRoIEJlcmdtYW5uJ3MgcnVsZSBpbiBtaW5kOyB0aGUgU291dGhlcm4gcmVnaW9uIGFjdHVhbGx5IGhhZCBhIGdyZWF0ZXIgYXZlcmFnZSwgc3RhdGlzdGljYWxseSBzaWduaWZpY2FudCwgYm9keSBtYXNzIGluIGdyYW1zLioqCgoqKkFzIHN0YXRlZCBhYm92ZSwgbXkgbW9kZWwgZmFpbGVkIGFzc3VtcHRpb25zLCBzbyBJIHNlbGVjdGVkIHRoZSBiZXN0LWZpdCBtb2RlbCB0byB0aGVzZSBhc3N1bXB0aW9ucy4gVGhlcmUgaXMgdGhlIHBvc3NpYmlsaXR5IHRoYXQgSSB1c2VkIHRoZSB3cm9uZyBHTE0uKioKCioqTXkgZmlndXJlIGFjY3VyYXRlIHJlcHJlc2VudHMgdGhlIHJlc3VsdHMgb2YgbXkgQU5PVkEuIElmIHlvdSB1c2UgdGhlIGV5ZWJhbGwgdGVzdCBvZiBjb25maWRlbmNlIGludGVydmFscywgeW91IGNhbiBzZWUgdGhhdCB0aGUgY29uZmlkZW5jZSBpbnRlcnZhbHMgZG8gbm90IG92ZXJsYXAsIHN1Z2dlc3RpbmcgYSBzdGF0aXN0aWNhbGx5IHNpZ25pZmljYW50IHJlc3VsdC4gSWYgeW91IGFyZ3VlIHRoYXQgdGhlIGNvbmZpZGVuY2UgaW50ZXJ2YWxzIGRvIG92ZXJsYXAsIHlvdSdkIGRvIHRoZSBhbmFseXNpcyB0byBmaW5kIHRoZSByZXN1bHRzIGFyZSBzaWduZmljYW50OiB0aGUgY29uZmlkZW5jZSBpbnRlcnZhbHMgZG8gbm90IG92ZXJsYXAgdGhlIG1lYW4hKioKCioqVWx0aW1hdGVseSwgbXkgYmlvbG9naWNhbCBxdWVzdGlvbiBmYWlsZWQsIGJ1dCBJIG1hbmFnZWQgdG8gZ2V0IGEgcmVzdWx0IHRoYXQgc3VnZ2VzdGVkIHRoYXQgb25lIHJlZ2lvbiBvZiBDaGluYSBoYWQgZ3JlYXRlciBib2R5IG1hc3MgKFNvdXRoZXJuKS4gSG93ZXZlciwgSSBtYW5hZ2VkIHRvIGRlc2NyaWJlIHNpZ25pZmljYW5jZSwgYnV0IHdoYXQgaXMgdGhlIG1hZ25pdHVkZSBvZiB0aGlzIHNpZ25pZmljYW5jZT8gSSByYW4gZWZmZWN0IHNpemUgdGVzdHMgYW5kIGZvdW5kIENvaGVuJ3MgRCBlZmZlY3Qgc2l6ZSB0byBiZSAtMC4zNDUgY29udHJhc3QgTm9ydGggLSBTb3V0aDsgZXRhIHNxdWFyZWQgb2YgZGlyZWN0aW9uIGlzIDclLiBUaGVzZSByZXN1bHRzIHN1Z2dlc3QgdG8gbWUgdGhhdCBhbHRob3VnaCBvdXIgcmVzdWx0cyBhcmUgc3RhdGlzdGljYWxseSBzaWduaWZpY2FudCwgdGhlcmUgaXMgbm8gcHJhY3RpY2FsIGFwcGxpY2F0aW9uIHRvIHRoaXMgc2lnbmZpY2FuY2Ugc2luY2Ugb3VyIGVmZmVjdCBzaXplIHZhbHVlcyBhcmUgc28gc21hbGwgdGhhdCBpdCBtYWtlcyBubyBzZW5zZSBpbiBhIGJpb2xvZ2ljYWwgY29udGV4dC4qKgoKKipJZiBJIHdlcmUgdG8gbWFrZSBhIHJlYXNvbmluZyBiZWhpbmQgbXkgZ3JhcGhlZCByZXN1bHRzIGRlc3BpdGUgdGhlIGxvdyBlZmZlY3Qgc2l6ZSwgSSB3b3VsZCBzYXkgc29tZSB2YXJpYWJsZSBob2xkcyBtb3JlIHdlaWdodCB0aGFuIHRoZSBlZmZlY3RvcnMgaW4gQmVyZ21hbm4ncyBydWxlOiBzb21ldGhpbmcgaW4gdGhlIFNvdXRoZXJuIHJlZ2lvbiBvZiBDaGluYSBpcyBjYXVzaW5nIGF2ZXJhZ2UgYm9keSBtYXNzIHRvIGJlIGJpZ2dlciwgZGVzcGl0ZSBhIHdhcm1lciBjbGltYXRlLioqCgoqKlRoZXJlIGFyZSBzb21lIG9idmlvdXMgbGltaXRhdGlvbnMgb2YgbXkgaW50ZXJwcmV0YXRpb24uIFRoZSBmaXJzdCBpcyB0aGF0IHNpbmNlIG91ciBhc3N1bXB0aW9ucyBmYWlsZWQsIHRoZW4gb3VyIGFuYWx5c2lzIGNvdWxkIGJlIGJpYXNlZC4gQW5vdGhlciBpcyBteSBkZWNpc2lvbiB0byBjbGFzc2lmeSByZWdpb25zIG9mIENoaW5hLiBJIHdhbnRlZCBhIGZhaXIgcmVwcmVzZW50YXRpb24gdG8gYmVnaW4gd2l0aCBteSBkYXRhLCBzbyBJIG1hZGUgQmVpamluZyBteSBjZW50ZXIgcG9pbnQgYW5kIGV2ZXJ5dGhpbmcgYWJvdmUgYW5kIGJlbG93IGlzIGZpbHRlcmVkIGFzIGEgY2VydGFpbiByZWdpb24uKioKCioqVGhlIGlzc3VlIHdpdGggdGhpcyBjbGFzc2lmaWNhdGlvbiBpcyB0aGF0IGl0IGRvZXNuJ3QgZXN0YWJsaXNoIHRoZSBwcm94aW1pdHkgb2YgdGhlc2UgY2l0aWVzLiBTb21lIG9mIHRoZXNlIGNpdGllcyBhcmUgYWN0dWFsbHkgcGFydCBvZiBjZW50cmFsIENoaW5hLCBhbmQgc29tZSBvZiB0aGVzZSBjaXRpZXMgYXJlIHBvcnQgY2l0aWVzLiBUaGVyZSdzIHRvbyBtdWNoIGRpdmVyc2lmaWNhdGlvbiwgYW5kIG15IGRlZ3JlZXMgb2YgZnJlZWRvbSBpbiBmb3JtYXR0aW5nIHRoZSBkYXRhIGNvdWxkJ3ZlIG1hZGUgbXkgcmVzdWx0cyBiaWFzZWQuKio=